package com.min.netty.file.constant;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import cn.hutool.crypto.digest.DigestUtil;
import org.apache.commons.io.FilenameUtils;

/**
 * 传输文件
 *
 * @author BBF
 */
public class TransferFile implements Serializable {

  private static final long serialVersionUID = 3782574170614337985L;
  /**
   * 传输的文件对象
   */
  private File file;

  /**
   * 文件MD5值
   */
  private String md5;

  /**
   * 文件扩展名，带点
   */
  private String ext;

  /**
   * 开始位置，用于标记分段上传的起始点
   */
  private Integer starPos;

  /**
   * 文件字节数组
   */
  private byte[] bytes;

  /**
   * 结尾位置
   */
  private Integer endPos;

  /**
   * 传输文件构造函数
   */
  public TransferFile() {
  }

  /**
   * 传输文件构造函数
   *
   * @param file 文件对象
   * @throws IOException 文件不存在、非文件、不可读时抛出异常
   */
  public TransferFile(File file) throws IOException {
    this(Paths.get(file.toURI()));
  }

  /**
   * 传输文件构造函数
   *
   * @param path 文件路径
   * @throws IOException 文件不存在、非文件、不可读时抛出异常
   */
  public TransferFile(String path) throws IOException {
    this(Paths.get(path));
  }

  /**
   * 传输文件构造函数
   *
   * @param path 文件路径
   * @throws IOException 文件不存在、非文件、不可读时抛出异常
   */
  public TransferFile(Path path) throws IOException {
    if (Files.notExists(path)) {
      throw new FileNotFoundException(path.toString());
    }
    if (Files.isDirectory(path)) {
      // 如果上传的不是文件，抛出异常
      throw new IOException(String.format(Constant.NOT_VALID_FILE, path.toString()));
    }
    if (!Files.isReadable(path)) {
      // 上传文件不可读，抛出异常
      throw new IOException(String.format(Constant.UNABLE_READ_FILE, path.toString()));
    }
    this.file = path.toFile();
    this.md5 = DigestUtil.md5Hex(file);
    String ext = FilenameUtils.getExtension(path.getFileName().toString());
    if (ext.length() > 0) {
      this.ext = "." + ext.toLowerCase();
    } else {
      this.ext = "";
    }
    this.starPos = 0;
    this.endPos = 0;
  }

  public File getFile() {
    return file;
  }

  public void setFile(File file) {
    this.file = file;
  }

  public String getMd5() {
    return md5;
  }

  public void setMd5(String md5) {
    this.md5 = md5;
  }

  public String getExt() {
    return ext;
  }

  public void setExt(String ext) {
    this.ext = ext;
  }

  public Integer getStarPos() {
    return starPos;
  }

  public void setStarPos(Integer starPos) {
    this.starPos = starPos;
  }

  public byte[] getBytes() {
    return bytes;
  }

  public void setBytes(byte[] bytes) {
    this.bytes = bytes;
  }

  public Integer getEndPos() {
    return endPos;
  }

  public void setEndPos(Integer endPos) {
    this.endPos = endPos;
  }
}
